package com.hxzy.framework.web.handler;

import com.hxzy.framework.common.exception.ApiException;
import com.hxzy.framework.common.exception.SaasApiException;
import com.hxzy.framework.common.resp.IErrorCode;
import com.hxzy.framework.common.resp.R;
import com.hxzy.framework.common.resp.ResultCode;
import lombok.extern.log4j.Log4j2;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;

import javax.validation.ConstraintViolationException;

/**
 * @Author wy
 * @Description web全局异常处理
 * @Date 2024/1/22 16:44
 * @Version 1.0
 */
@RestControllerAdvice
@Log4j2
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public R<Object> handle(Exception exception) {
        log.error(exception);
        return R.failed(exception.getMessage());
    }

    @ExceptionHandler(value = ApiException.class)
    public R<Object> handle(ApiException exception) {
        log.error(exception);
        IErrorCode errorCode = exception.getErrorCode();
        return R.failed(errorCode, errorCode.getMessage());
    }


    /**
     * 参数json校验异常处理
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R<Object> handle(MethodArgumentNotValidException exception) {
        log.error(exception);
        FieldError fieldError = (FieldError) exception.getBindingResult().getAllErrors().get(0);
        String errMsg = "参数 - " + fieldError.getField() + " : " + fieldError.getDefaultMessage();
        return R.failed(errMsg);
    }

    /**
     * validation表单验证异常
     * @param bindException
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    public R exceptionHandler(BindException bindException) {
        log.error(bindException);
        String errMsg = bindException.getAllErrors().get(0).getDefaultMessage();
        return R.failed(errMsg);
    }


    /**
     * validation单个参数验证异常
     * @param constraintViolationException
     * @return
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    public R methodArgumentNotValidException(ConstraintViolationException constraintViolationException) {
        log.error(constraintViolationException);
        String errMsg = constraintViolationException.getLocalizedMessage();
        return R.failed(errMsg);
    }


    /**
     * 处理自定义异常
     * @param saasApiException
     * @return
     */
    @ExceptionHandler(value = SaasApiException.class)
    public R exceptionHandler(SaasApiException saasApiException){
        log.error(saasApiException);
        return R.failed(saasApiException.getMessage());
    }



    /**
     * @author qy
     * @date 2021/8/17
     * @description 文件上传大小限制
     **/
    @ExceptionHandler(value = MultipartException.class)
    public R fileUploadException(MultipartException e){
        // 记录异常日志
        log.error("[fileUploadException]", e);
        return R.failed(ResultCode.FAILED, "文件大小超过限制2M");
    }

}
